class Booking {
    constructor(show, date) {
        this._show = show;
        this._date = date;
    }

    get hasTalkback() {
        return this._show.hasOwnProperty("talkback") && !this.isPeakDay;
    }

    get basePrice() {
        let result = this._show.price;
        if (this.isPeakDay) {
            result += Math.round(result * 0.15);
        }
        return result;
    }
}

class PremiumBooking extends Booking {
    constructor(show, date, extras) {
        super(show, date);
        this._extras = extras;
    }

    get hasTalkback() {
        return this._show.hasOwnProperty("talkback");
    }

    get basePrice() {
        return Math.round(super.basePrice + this._extras.premiumFee);
    }

    get hasDinner() {
        return this._extras.hasOwnProperty("dinner") && !this.isPeakDay;
    }
}

var aBooking = new Booking(show, date);
var aBooking = new PremiumBooking(show, date, extras);
/**************************************************************************** */
class Booking {
    constructor(show, date) {
        this._show = show;
        this._date = date;
    }

    get hasTalkback() {
        return (this._premiumDelegate) ? this._premiumDelegate.hasTalkback : this._show.hasOwnProperty("talkback") && !this.isPeakDay;
    }

    get basePrice() {
        let result = this._show.price;
        return (this._premiumDelegate) ? this._premiumDelegate.extendBasePrice(result) : Math.round(super.basePrice + this._extras.premiumFee);
    }

    _bePremium(extras) {
        this._premiumDelegate = new PremiumBookingDelegate(this, extras);
    }

    get hasDinner() {
        return (this.premiumFee) ? this._premiumDelegate.hasDinner : undefined;
    }
}

function createBooking(show, date) {
    return new Booking(show, date);
}

function createPremiumBooking(show, date, extras) {
    const result = new Booking(show, date, extras);
    result._bePremium(extras);
    return result;
}

// 普通给客户端的预定
aBooking = createBooking(show, date);
// 高级客户端的预定
aBooking = createPremiumBooking(show, date, extras);

// 委托类
class PremiumBookingDelegate {
    constructor(hostBooking, extras) {
        this._host = hostBooking;
        this._extras = extras;
    }

    get hasTalkback() {
        return this._host._show.hasOwnProperty("talkback");
    }

    extendBasePrice(base) {
        return Math.round(base + this._extras.premiumFee);
    }

    get hasDinner() {
        return this._extras.hasOwnProperty("dinner") && !this._host.isPeakDay;
    }

}